home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
ai
/
vgamaze4
/
oracle.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-13
|
3KB
|
96 lines
#include "oracle.h"
#define TRUE -1
#define FALSE 0
oracle::oracle(char *seed,int max_r_n_plus_1)
// An eight (or fewer) character seed and the upper bound on the
// numbers to be returned specify the random number generator.
{
modulus=max_r_n_plus_1;
prime=equal_or_larger_prime(modulus);
// A prime modulus is needed to insure that the number returned from
// the random number generator are uniformly distributed.
for (int r_n_index_1=0; ((r_n_index_1 < 8) && (seed[r_n_index_1]));
r_n_index_1++) // insert seed
{
if (seed[r_n_index_1] < '\0')
seed[r_n_index_1]=-seed[r_n_index_1];
r_n[r_n_index_1]=long(seed[r_n_index_1])%prime;
}
int r_n_index_2=7;
while (r_n_index_1 > 0) // right justify
{
r_n_index_1--;
r_n[r_n_index_2]=r_n[r_n_index_1];
r_n_index_2--;
}
while (r_n_index_2 >= 0) // fill with leading 1's
{
r_n[r_n_index_2]=1;
r_n_index_2--;
}
}
long oracle::equal_or_larger_prime(int starting_value)
// Try consecutive values until a prime number is found.
{
long result=long(starting_value);
while (! is_prime(result)) result++;
return result;
}
int oracle::is_prime(long possible_prime)
// If no number up to the square root of a number evenly divides the
// number, then the number is prime.
{
long new_max_divisor;
int result=TRUE;
long max_divisor=possible_prime;
int square_root=FALSE;
while (! square_root)
{
if ((new_max_divisor=(max_divisor+possible_prime/max_divisor)/2l)
< max_divisor)
max_divisor=new_max_divisor;
else
square_root=TRUE;
} // max_divisor=sqrt(possible_prime) via Newton's method.
for (long divisor=2l; ((result) && (divisor <= max_divisor)); divisor++)
result=((divisor*(possible_prime/divisor)) != possible_prime);
return result;
}
int oracle::random_number()
// Ignoring initialization, r_n[i] is the sum of the 8 previous values of
// r_n[i] mod prime. r_n[7] is computed until it's within the desired range and
// then it's returned.
// It is assumed that a "long" can contain the sum of any two "int"s.
{
int r_n_index_1;
int r_n_index_2;
long result;
long tem_long;
do
{
result=r_n[0];
r_n_index_1=0;
r_n_index_2=1;
while (r_n_index_2 < 8)
{
tem_long=r_n[r_n_index_2];
r_n[r_n_index_1]=tem_long;
result+=tem_long;
if (result >= prime)
result-=prime;
r_n_index_1=r_n_index_2;
r_n_index_2++;
}
r_n[7]=result;
}
while (result >= long(modulus));
return int(result);
}